using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using SkinnedModel;

namespace A_stain_on_the_planet
{
    class FishLevel
    {
        Game1 m_game;
        int m_MaxNumberFish = 4;
        int m_NumberOfFishesSaved;
        int m_NumberOfDeadFish;
        Vector2 m_Spawnpoint1, m_Spawnpoint2, m_Spawnpoint3, m_Spawnpoint4, m_Spawnpoint5;
        float m_spawntimer;
        float m_GameTime;
        float m_GameTimeTien;
        float m_Seconden;
        float m_SecondenTien;
        float m_Minuten;
        Texture2D m_texFish;
        Texture2D m_texBackground;
        Texture2D m_texOilTop;
        Texture2D m_Algen;
        Texture2D m_texOilAvoid;
        Texture2D m_TexScore;
        Texture2D m_TexTimer;
        int m_AlgenSpawner;
        int m_tellerOilTop;
        int m_TellerFrames;
        float m_rotate;
        List<Algen> m_AlgenList;
        List<Fish> m_FishList;
        List<BoundingBox> m_BoundingBoxScreen;
        List<OlieVlek> m_OilList;
        ContentManager m_content;
        SpriteFont Font1;
        System.Random generator = new System.Random();
        EventHandler m_Eventhandler;


        
        

       public FishLevel(Game1 game, int MaxFish)
       {
           m_game = game;
           m_MaxNumberFish = MaxFish;
       }

       public void Initialize(ContentManager content, EventHandler eventhandler)
       {
           m_Eventhandler = eventhandler;

           m_Spawnpoint1 = new Vector2(-100, 150);
           m_Spawnpoint2 = new Vector2(-100, 600);
           m_Spawnpoint3 = new Vector2(400, 600);
           m_Spawnpoint4 = new Vector2(900, 600);
           m_Spawnpoint5 = new Vector2(900, 150);

           
           Font1 = content.Load<SpriteFont>("Times New Roman");
           int rand = generator.Next(1, 3);

           if (rand == 1) m_texBackground = content.Load<Texture2D>("BG1b4");
           else m_texBackground = content.Load<Texture2D>("BG2a4");

           m_texOilTop = content.Load<Texture2D>("OilFloatAnimated_Tiled");

           m_Algen = content.Load<Texture2D>("AlgaeAnimatedSprite_Shaded");

           m_texOilAvoid = content.Load<Texture2D>("AnimatedOilSpot2_Transparant");

           m_TexScore = content.Load<Texture2D>(@"Backgrounds\INT2_Scores_Sprites");

           m_TexTimer = content.Load<Texture2D>(@"Backgrounds\TimerOvalWhite");

           m_BoundingBoxScreen = new List<BoundingBox>();
           m_AlgenList = new List<Algen>();

           BoundingBox Outside = new BoundingBox(new Vector3(-1000, -500, 0), new Vector3(0, 980, 0));
           m_BoundingBoxScreen.Add(Outside);
          
           Outside = new BoundingBox(new Vector3(800, -500, 0), new Vector3(1810, 980, 0));
           m_BoundingBoxScreen.Add(Outside);

           Outside = new BoundingBox(new Vector3(-500, -1000, 0), new Vector3(13000, 0, 0));
           m_BoundingBoxScreen.Add(Outside);

           Outside = new BoundingBox(new Vector3(-500, 480, 0), new Vector3(1300, 1490, 0));
           m_BoundingBoxScreen.Add(Outside);

           m_FishList = new List<Fish>();
           m_OilList = new List<OlieVlek>();

           rand = generator.Next(1, 4);

           if(rand == 1) m_texFish = content.Load<Texture2D>(@"MainCharacters\FishAnimatedSprite_final_ThreeFourths");
           else if (rand == 2) m_texFish = content.Load<Texture2D>(@"MainCharacters\FishAnimatedSprite_final_ThreeFourthsGreen_Recolor1");
           else m_texFish = content.Load<Texture2D>(@"MainCharacters\FishAnimatedSprite_final_ThreeFourthsGreen_Recolor2");

           rand = generator.Next(1, 6);

           Fish newfish;

           if (rand == 1) newfish = new Fish(this, m_Spawnpoint1, m_texFish, new Vector2(8, 0));
           else if (rand == 2) newfish = new Fish(this, m_Spawnpoint2, m_texFish, new Vector2(8, -8));
           else if (rand == 3) newfish = new Fish(this, m_Spawnpoint3, m_texFish, new Vector2(0, -8));
           else if (rand == 4) newfish = new Fish(this, m_Spawnpoint4, m_texFish, new Vector2(-8, -8));
           else newfish = new Fish(this, m_Spawnpoint5, m_texFish, new Vector2(-8, 0));

           m_AlgenSpawner = generator.Next(0, 7);

           m_FishList.Add(newfish);

           m_FishList.ForEach(delegate(Fish fish)
           {
               fish.Initialize(content);
           });

           m_content = content;
       }

       public void Draw(GameTime gametime, SpriteBatch spritebatch, GraphicsDeviceManager graphics)
       {
           

           spritebatch.Draw(m_texBackground, new Rectangle(0, 0, 800, 480), Color.White);
           spritebatch.Draw(m_texOilTop, new Rectangle(0, 0, 800, 84), new Rectangle(0, m_tellerOilTop * 84, 800, 84), Color.White);

           spritebatch.Draw(m_TexScore, new Rectangle(40, 10, m_TexScore.Width / 6, m_TexScore.Height / 4)
               , new Rectangle(m_TexScore.Width / 3, 0, m_TexScore.Width / 3, m_TexScore.Height / 2), Color.White);

           string output = " " + m_NumberOfFishesSaved.ToString() + "/15";

           Vector2 FontOrigin = Font1.MeasureString(output) / 2;
           FontOrigin.X -= 150;

           spritebatch.DrawString(Font1, output, new Vector2(-20, 35), Color.Black, 0, FontOrigin, 1.0f, SpriteEffects.None, 0.5f);

           spritebatch.Draw(m_TexScore, new Rectangle(40, 35, m_TexScore.Width / 6, m_TexScore.Height / 4)
              , new Rectangle(m_TexScore.Width / 3, m_TexScore.Height / 2, m_TexScore.Width / 3, m_TexScore.Height / 2), Color.White);

           output = "  " + m_NumberOfDeadFish.ToString() + "/5";

           FontOrigin = Font1.MeasureString(output) / 2;
           FontOrigin.X -= 150;

           spritebatch.DrawString(Font1, output, new Vector2(-20, 70), Color.Black, 0, FontOrigin, 1.0f, SpriteEffects.None, 0.5f);
           spritebatch.Draw(m_TexTimer, new Rectangle(530, 55, (int)(m_TexTimer.Width / 1.5f), (int)(m_TexTimer.Height / 1.5f)), Color.White);

           output = m_Minuten + ":" + m_SecondenTien + m_Seconden;

           if ((m_GameTime / 10) >= 10)
           {
               m_GameTime = 0;
               ++m_GameTimeTien;

               if (m_GameTimeTien >= 10)
               {
                   m_GameTimeTien = 0;
                   ++m_Seconden;

                   if (m_Seconden >= 10)
                   {
                       m_Seconden = 0;
                       ++m_SecondenTien;

                       if (m_SecondenTien >= 6)
                       {
                           m_SecondenTien = 0;
                           ++m_Minuten;
                       }
                   }
               }
           }

           FontOrigin = Font1.MeasureString(output) / 2;
           FontOrigin.X -= 150;

           spritebatch.DrawString(Font1, output, new Vector2(420, 74), Color.Black, 0, FontOrigin, 1.0f, SpriteEffects.None, 0.5f);

           m_AlgenList.ForEach(delegate(Algen Alg)
           {
               Alg.Draw(gametime, spritebatch);
           });

           

           m_FishList.ForEach(delegate(Fish fish)
           {
               fish.Draw(gametime, spritebatch, graphics);
           });

           m_OilList.ForEach(delegate(OlieVlek vlek)
           {
               vlek.draw(spritebatch);
           });

           //spritebatch.Draw(m_texSea, new Vector2(0, 440), Color.White);

          
       }

       public void Update(GameTime gametime)
       {
           m_rotate += 0.1f;

           m_GameTime += gametime.ElapsedGameTime.Milliseconds;

           m_AlgenSpawner += gametime.ElapsedGameTime.Milliseconds;

           if(m_AlgenSpawner >= 10000)
           {
               if (m_NumberOfFishesSaved <= 5)
               {
                   for (int i = 0; i < 3; ++i)
                   {
                       int Spawnpos = generator.Next(50, 750);
                       int SpawnposY = generator.Next(500, 700);

                       Algen NewAlg = new Algen(this, new Vector2(Spawnpos, SpawnposY), m_Algen);
                       m_AlgenList.Add(NewAlg);
                   }

                   m_AlgenSpawner = generator.Next(0, 9) * 1000;

                   int SpawnposOil = generator.Next(50, 750);
                   int velocity = 0;

                   if (SpawnposOil <= 400) velocity = generator.Next(0, 7);
                   else velocity = generator.Next(-6, 1);

                   int width = generator.Next(100, 200);
                   int height = generator.Next(100, 200);

                   OlieVlek NewVlek = new OlieVlek(new Vector2(SpawnposOil, -300), new Vector2(velocity, 10), m_texOilAvoid, width, height);
                   m_OilList.Add(NewVlek);             
               }

               else if (m_NumberOfFishesSaved <= 9)
               {
                   for (int i = 0; i < 2; ++i)
                   {
                       int Spawnpos = generator.Next(50, 750);
                       int SpawnposY = generator.Next(500, 700);

                       Algen NewAlg = new Algen(this, new Vector2(Spawnpos, SpawnposY), m_Algen);
                       m_AlgenList.Add(NewAlg);
                   }

                   m_AlgenSpawner = generator.Next(0, 9) * 1000;

                   int SpawnposOil = generator.Next(50, 750);
                   int velocity = 0;

                   if (SpawnposOil <= 400) velocity = generator.Next(0, 7);
                   else velocity = generator.Next(-6, 1);

                   int width = generator.Next(50, 150);
                   int height = generator.Next(50, 150);

                   OlieVlek NewVlek = new OlieVlek(new Vector2(SpawnposOil, -300), new Vector2(velocity, 10), m_texOilAvoid, width, height);
                   m_OilList.Add(NewVlek);  
               }

               else 
               {
                   int Spawnpos = generator.Next(50, 750);
                   int SpawnposY = generator.Next(500, 700);

                   Algen NewAlg = new Algen(this, new Vector2(Spawnpos, SpawnposY), m_Algen);
                   m_AlgenList.Add(NewAlg);

                   m_AlgenSpawner = generator.Next(0, 9) * 1000;

                   int SpawnposOil = generator.Next(50, 750);
                   int velocity = 0;

                   if (SpawnposOil <= 400) velocity = generator.Next(0, 7);
                   else velocity = generator.Next(-6, 1);

                   int width = generator.Next(100, 200);
                   int height = generator.Next(100, 200);

                   OlieVlek NewVlek = new OlieVlek(new Vector2(SpawnposOil, -300), new Vector2(velocity, 10), m_texOilAvoid, width, height);
                   m_OilList.Add(NewVlek);  
               }

               
           }

           m_AlgenList.ForEach(delegate(Algen Alg)
           {
               Alg.update();

               m_FishList.ForEach(delegate(Fish fish)
               {
                   if (Alg.ColisionBox.Intersects(fish.Hoofd))
                   {
                       fish.HasEaten = true;

                       m_Eventhandler.SFXSwallowAlgae();

                       m_AlgenList.Remove(Alg);
                   }
               });
           });

           m_OilList.ForEach(delegate(OlieVlek vlek)
           {
               vlek.update();

               m_FishList.ForEach(delegate(Fish fish)
               {
                   if (vlek.ColisionBox.Intersects(fish.Hoofd))
                   {
                       if (fish.Isimmortal == false && fish.IsDead == false)
                       {
                           fish.IsDead = true;
                           m_Eventhandler.FishLost((int)fish.Boundingbox.Min.X, (int)fish.Boundingbox.Min.Y);
                       }
                   }
               });

               m_AlgenList.ForEach(delegate(Algen Alg)
               {
                   if (Alg.ColisionBox.Intersects(vlek.ColisionBox))
                   {
                       m_AlgenList.Remove(Alg);
                   }
               });

               if (vlek.position.Y >= 500)
               {
                   m_OilList.Remove(vlek);
  
               }
           });


           ++m_TellerFrames;
           if (m_TellerFrames >= 4)
           {
               ++m_tellerOilTop;
               if (m_tellerOilTop >= 18) m_tellerOilTop = 0;
               m_TellerFrames = 0;
           }


           if (m_FishList.Count < m_MaxNumberFish)
           {
               m_spawntimer += (float) gametime.ElapsedGameTime.TotalSeconds;

               if (m_spawntimer >= 8)
               {

                   int rand = generator.Next(1, 4);

                   if (rand == 1) m_texFish = m_content.Load<Texture2D>(@"MainCharacters\FishAnimatedSprite_final_ThreeFourths");
                   else if (rand == 2) m_texFish = m_content.Load<Texture2D>(@"MainCharacters\FishAnimatedSprite_final_ThreeFourthsGreen_Recolor1");
                   else m_texFish = m_content.Load<Texture2D>(@"MainCharacters\FishAnimatedSprite_final_ThreeFourthsGreen_Recolor2");

                   rand = generator.Next(1, 6);

                   Fish newfish;

                   if (rand == 1) newfish = new Fish(this, m_Spawnpoint1, m_texFish, new Vector2(8, 0));
                   else if (rand == 2) newfish = new Fish(this, m_Spawnpoint2, m_texFish, new Vector2(8, -8));
                   else if (rand == 3) newfish = new Fish(this, m_Spawnpoint3, m_texFish, new Vector2(0, -8));
                   else if (rand == 4) newfish = new Fish(this, m_Spawnpoint4, m_texFish, new Vector2(-8, -8));
                   else newfish = new Fish(this, m_Spawnpoint5, m_texFish, new Vector2(-8, 0));
                   newfish.Initialize(m_content);
                   m_FishList.Add(newfish);

                    m_spawntimer = 0;      
               }
           }

           m_FishList.ForEach(delegate(Fish fish)
           {
               fish.Update(gametime);

               m_BoundingBoxScreen.ForEach(delegate(BoundingBox outside)
               {
                   if (fish.Boundingbox.Intersects(outside))
                   {
                       

                       if (fish.IsDead == true && fish.Position.Y <= 5)
                       {
                           RemoveFish(fish, false);
                       }

                       else if (fish.HasEaten == false)
                       {
                           

                           if (fish.Velocity.X < 0 && fish.Position.X <= 5) fish.Velocity = new Vector2(-fish.Velocity.X, fish.Velocity.Y);
                           else if (fish.Velocity.X > 0 && fish.Position.X >= 595) fish.Velocity = new Vector2(-fish.Velocity.X, fish.Velocity.Y);
                           else if (fish.Velocity.Y < 0 && fish.Position.Y <= 5) fish.Velocity = new Vector2(fish.Velocity.X, -fish.Velocity.Y);
                           else if (fish.Velocity.Y > 0 && fish.Position.Y >= 395) fish.Velocity = new Vector2(fish.Velocity.X, -fish.Velocity.Y);
                       }


                       else
                       {
                           if (fish.Velocity.X < 0 && fish.Position.X <= 5) fish.Velocity = new Vector2(-10, fish.Velocity.Y);
                           else if (fish.Velocity.X > 0 && fish.Position.X >= 595) fish.Velocity = new Vector2(10, fish.Velocity.Y);
                           else if (fish.Velocity.Y < 0 && fish.Position.Y <= 5) fish.Velocity = new Vector2(fish.Velocity.X, -fish.Velocity.Y);
                           else if (fish.Velocity.Y > 0 && fish.Position.Y >= 395) fish.Velocity = new Vector2(fish.Velocity.X, 10);

                           m_Eventhandler.SFXPing();

                           if (fish.Position.X <= -100)
                           {
                               RemoveFish(fish, true);
                           }
                           else if (fish.Position.X >= 695)
                           {
                               RemoveFish(fish, true);
                           }
                           else if (fish.Position.Y >= 495)
                           {
                               RemoveFish(fish, true);
                           }
                       }
                   }
               });
           });
       }

        public void RemoveFish(Fish fish, bool saved)
        {

            m_Eventhandler.SFXPing();

            m_FishList.Remove(fish);

            if (saved == true) 
            {
                m_NumberOfFishesSaved++;
                m_game.ChangeScore(100);
                if (m_NumberOfFishesSaved >= 15) m_game.Victory();
                
            }

            else
            {
                m_game.ChangeScore(-50);
                m_NumberOfDeadFish++;

                if (m_NumberOfDeadFish >= 5) m_game.GameOver();
            }
       }

        public List<Fish> GetFishList
        {
            get { return m_FishList; }
        }

        public int DeadFish
        {
            get { return m_NumberOfDeadFish; }
        }

        public float Time
        {
            get { return m_GameTime + (m_GameTimeTien * 100) + (m_Seconden * 1000) + (m_SecondenTien * 10000) + (m_Minuten * 100000); }
        }

        public void draw3D(GameTime gametime, GraphicsDeviceManager graphics)
        {
            m_FishList.ForEach(delegate(Fish fish)
            {
                fish.Draw3D(gametime, graphics);
            });
        }
    }
}
